package com.linking.third.party.manager.alipay;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.google.common.collect.Maps;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.Map;


public class AlipayOrderInfoUtils {

  /**
   * 构造支付订单参数列表
   *
   * @param appId
   * @return
   */
  public static Map<String, String> buildOrderParamMap(String appId, String notifyUrl,
      AlipayBizContent alipayBizContent) {
    Map<String, String> keyValues = Maps.newHashMap();
    keyValues.put("app_id", appId);
    keyValues.put("biz_content", JSON.toJSONString(alipayBizContent));
    keyValues.put("charset", "utf-8");
    keyValues.put("method", "alipay.trade.app.pay");
    keyValues.put("notify_url", notifyUrl);
    keyValues.put("sign_type", "RSA2");
    keyValues.put("timestamp", DateUtil.format(DateUtil.date(), "YYYY-MM-dd HH:mm:ss"));
    keyValues.put("version", "1.0");
    return keyValues;
  }

  /**
   * 构造支付订单参数信息
   *
   * @param map 支付订单参数
   * @return
   */
  public static String buildOrderParam(Map<String, String> map) {
    List<String> keys = new ArrayList<>(map.keySet());
    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < keys.size() - 1; i++) {
      String key = keys.get(i);
      String value = map.get(key);
      sb.append(buildKeyValue(key, value, true));
      sb.append("&");
    }
    String tailKey = keys.get(keys.size() - 1);
    String tailValue = map.get(tailKey);
    sb.append(buildKeyValue(tailKey, tailValue, true));
    return sb.toString();
  }

  /**
   * 拼接键值对
   *
   * @param key
   * @param value
   * @param isEncode
   * @return
   */
  private static String buildKeyValue(String key, String value, boolean isEncode) {
    StringBuilder sb = new StringBuilder();
    sb.append(key);
    sb.append("=");
    if (isEncode) {
      try {
        sb.append(URLEncoder.encode(value, "UTF-8"));
      } catch (UnsupportedEncodingException e) {
        sb.append(value);
      }
    } else {
      sb.append(value);
    }
    return sb.toString();
  }

  /**
   * 对支付参数信息进行签名
   *
   * @param map 待签名授权信息
   * @return
   */
  public static String getSign(Map<String, String> map, String rsaKey) {
    List<String> keys = new ArrayList<String>(map.keySet());
    // key排序
    Collections.sort(keys);

    StringBuilder authInfo = new StringBuilder();
    for (int i = 0; i < keys.size() - 1; i++) {
      String key = keys.get(i);
      String value = map.get(key);
      authInfo.append(buildKeyValue(key, value, false));
      authInfo.append("&");
    }

    String tailKey = keys.get(keys.size() - 1);
    String tailValue = map.get(tailKey);
    authInfo.append(buildKeyValue(tailKey, tailValue, false));

    String oriSign = AlipaySignUtils.sign(authInfo.toString(), rsaKey);
    String encodedSign = "";

    try {
      encodedSign = URLEncoder.encode(oriSign, "UTF-8");
    } catch (UnsupportedEncodingException e) {
      e.printStackTrace();
    }
    return "sign=" + encodedSign;
  }

  /**
   * 要求外部订单号必须唯一。
   *
   * @return
   */
  public static String getOutTradeNo() {
    SimpleDateFormat format = new SimpleDateFormat("MMddHHmmss", Locale.getDefault());
    Date date = new Date();
    String key = format.format(date);
    key = key + System.currentTimeMillis();
    key = key.substring(0, 15);
    return key;
  }

}
